package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.PutObjectResult;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.MessageConstant;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.UUIDUtils;
import com.nineclock.message.enums.MessageTypeEnum;
import com.nineclock.message.pojo.NcMessage;
import com.nineclock.system.dto.SysAllowedJoinCompanyUserDTO;
import com.nineclock.system.dto.SysApplyJoinCompanyUserDTO;
import com.nineclock.system.dto.SysChangeMainManagerDTO;
import com.nineclock.system.dto.SysCompanyDTO;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SysCompanyService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@Service
@Slf4j
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    private SysCompanyMapper companyMapper;

    /**
     * @return
     */
    @Override
    public SysCompanyDTO queryCompanyInfo() {
        Long companyId = CurrentUserHolder.get().getCompanyId();

        SysCompany sysCompany = companyMapper.selectById(companyId);

        if (sysCompany == null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }


        return BeanHelper.copyProperties(sysCompany, SysCompanyDTO.class);
    }

    @Autowired
    private OSS oss;
    @Autowired
    private OssProperties ossProperties;

    /**
     * 获取企业logo标识
     *
     * @param file
     * @return
     */
    @SneakyThrows
    @Override
    public String uploadCompanyLogo(MultipartFile file) {
        //判断上传的文件是否为空
        if (file == null) {
            throw new NcException(ResponseEnum.FILE_UPLOAD_ERROR);
        }
        String contentType = file.getContentType();
        //判断文件类型是否为img类型
        if (!NcConstant.ALLOWED_IMG_TYPES.contains(contentType)) {
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }
        //判断文件大小是否超容
        if (file.getSize() > NcConstant.maxFileSize) {

            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }
//        file.getOriginalFilename() 获取原始文件名(包含后缀)
//        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
//        String fileName = dateFormat.format(new Date()) + file.getOriginalFilename();

        String uuid = UUIDUtils.getUUID();
        String name = file.getOriginalFilename();
        String substring = name.substring(name.lastIndexOf("."));
        String key = uuid + substring;

        //图片上传( 存储空间名称 ， 文件名， 文件流对象 )
        PutObjectResult putObjectResult = oss.putObject(ossProperties.getBucketName(), key, file.getInputStream());
        log.info("上传图片的结果:" + putObjectResult);
        String filePath = String.format(ossProperties.getHost(), ossProperties.getBucketName()) + key;
        log.info("企业logo路径:" + filePath);
        return filePath;
    }

    @Override
    public void updateCompanyInfo(SysCompanyDTO sysCompanyDTO) {

        if (sysCompanyDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        Long companyId = CurrentUserHolder.get().getCompanyId();
        SysCompany company = companyMapper.selectById(companyId);
        if (company == null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        company.setLogo(sysCompanyDTO.getLogo());
        company.setName(sysCompanyDTO.getName());
        companyMapper.updateById(company);
    }

    @Autowired
    SysCompanyUserMapper companyUserMapper;

    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    @Autowired
    SysRoleMapper roleMapper;

    /**
     * 1. 健壮性判断
     * 2. 新管理员 是否存在
     * 3. 校验验证码是否正确
     * 4. 删除原管理员与角色的关系， 添加新管理员的关系
     *
     * @param sysChangeMainManagerDTO
     */
    @Override
    public void changeSysAdmin(SysChangeMainManagerDTO sysChangeMainManagerDTO) {

        if (sysChangeMainManagerDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        Long companyId = CurrentUserHolder.get().getCompanyId();

        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(SysCompanyUser::getCompanyId, companyId);
        wrapper.eq(SysCompanyUser::getEnable, 1);
        wrapper.eq(SysCompanyUser::getId, sysChangeMainManagerDTO.getUserId());

        SysCompanyUser companyUser = companyUserMapper.selectOne(wrapper);//获取新主管理员的信息
        //验证新管理员是否存在
        if (companyUser == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);

        }
        String code = sysChangeMainManagerDTO.getCode();

        String key = SMSConstant.SMS_RESET_KEY_PREFIX + companyUser.getMobile();
        String redisCode = redisTemplate.boundValueOps(key).get();
        if (redisCode == null || !redisCode.equals(code)) {
            throw new NcException(ResponseEnum.INVALID_VERIFY_CODE);
        }
        LambdaQueryWrapper<SysRole> roleQw = new LambdaQueryWrapper<>();
        roleQw.eq(SysRole::getRoleName, "ROLE_ADMIN_SYS");
        roleQw.eq(SysRole::getCompanyId, companyId);
        SysRole role = roleMapper.selectOne(roleQw);

        //删除原管理员关系
        LambdaQueryWrapper<SysCompanyUserRole> companyUserRoleQw = new LambdaQueryWrapper<>();
        companyUserRoleQw.eq(SysCompanyUserRole::getCompanyId, companyId);
        companyUserRoleQw.eq(SysCompanyUserRole::getCompanyUserId, CurrentUserHolder.get().getCompanyUserId());
        companyUserRoleQw.eq(SysCompanyUserRole::getRoleId, role.getId());
        companyUserRoleMapper.delete(companyUserRoleQw);

        //添加信息的关系
        SysCompanyUserRole companyUserRole = new SysCompanyUserRole();
        companyUserRole.setCompanyId(companyId);
        companyUserRole.setRoleId(role.getId());
        companyUserRole.setCompanyUserId(sysChangeMainManagerDTO.getUserId());

        companyUserRoleMapper.insert(companyUserRole);


    }

    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(SysCompany::getName, keyword);
        List<SysCompany> companies = companyMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(companies)) {
            return BeanHelper.copyWithCollection(companies, SysCompanyDTO.class);
        }
        return null;
    }

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 申请加入企业
     *
     * @param sysApplyJoinCompanyUserDTO
     */
    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO sysApplyJoinCompanyUserDTO) {
        if (sysApplyJoinCompanyUserDTO == null || sysApplyJoinCompanyUserDTO.getUserId() == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        SysUser sysUser = sysUserMapper.selectById(sysApplyJoinCompanyUserDTO.getUserId());

        if (sysUser == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        sysUser.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        sysUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());
        sysUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        sysUser.setLastLoginCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        sysUserMapper.updateById(sysUser);

        if (sysApplyJoinCompanyUserDTO.getCompanyId() == null) {
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        SysCompanyUser companyUser = new SysCompanyUser();
        companyUser.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        companyUser.setCompanyName(sysApplyJoinCompanyUserDTO.getCompanyName());
        companyUser.setImageUrl(sysApplyJoinCompanyUserDTO.getImageUrl());
        companyUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());
        companyUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        companyUser.setPost(sysApplyJoinCompanyUserDTO.getPost());
        companyUser.setUserId(sysApplyJoinCompanyUserDTO.getUserId());
        companyUser.setUserName(sysApplyJoinCompanyUserDTO.getUserName());
        companyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason());

        companyUser.setEnable((short) 0);
        companyUserMapper.insert(companyUser);

        //TODO 发送消息到MQ , 推送消息,通知管理员
        //查询企业主管理员
        SysCompanyUser companyAdmin = companyUserMapper.queryMainAdminCompanyUser(sysApplyJoinCompanyUserDTO.getCompanyId());

        //发送消息到MQ , 推送消息,通知管理员
//查询企业主管理员
        SysCompanyUser currentAdmin = companyUserMapper.queryMainAdminCompanyUser(sysApplyJoinCompanyUserDTO.getCompanyId());

//发送消息到MQ , 推送消息,通知管理员
        if (currentAdmin != null) {
            NcMessage message = new NcMessage();
            message.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType()); //消息类型 ：团队申请
            message.setApplyUserId(sysUser.getId()); //apply  申请人
            message.setApplyUsername(sysUser.getUsername()); //申请人用户名

            message.setApproveUserId(currentAdmin.getUserId()); // 当前管理员 用户id
            message.setApproveUsername(currentAdmin.getUserName()); //管理员用户名
            message.setApproveStatue(0); // 审批状态
            message.setTargets(Arrays.asList(currentAdmin.getMobile())); //管理员手机号


            message.setUseStatus(0); // 消息使用状态
            message.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle()); // 消息标题
            message.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience()); // 推送消息的类型
            message.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId() + ""); //企业id

            //推送内容
            message.setContent(sysUser.getUsername() + "申请加入企业，请及时审批");

            //推送消息（topic  推送的标题）
            rocketMQTemplate.convertAndSend("messagePushTopic", message);

        }
    }

    //审核加入企业
    @Override
    public void allowedJoinCompany(SysAllowedJoinCompanyUserDTO sysAllowedJoinCompanyUserDTO) {
        if (sysAllowedJoinCompanyUserDTO == null) {
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        LambdaQueryWrapper<SysCompanyUser> companyUserQw = new LambdaQueryWrapper<>();

        companyUserQw.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        companyUserQw.eq(SysCompanyUser::getUserId, sysAllowedJoinCompanyUserDTO.getApplyUserId());

        SysCompanyUser companyUser = companyUserMapper.selectOne(companyUserQw);
        companyUserMapper.selectOne(companyUserQw);
        //修改审核状态
        if (companyUser != null) {
            companyUser.setRemark(sysAllowedJoinCompanyUserDTO.getRemark());
            companyUser.setEnable(sysAllowedJoinCompanyUserDTO.getApproved() ? (short) 1 : (short) 0);
            companyUserMapper.updateById(companyUser);
        }
        if (sysAllowedJoinCompanyUserDTO.getApproved()) {
            //如果审批通过

            //发送消息到MQ, 更新加入团队申请的消息状态 为已审核通过;
            rocketMQTemplate.convertAndSend("allowedJoinCompanyTopic", sysAllowedJoinCompanyUserDTO.getNotifyMsgId());

            //发送消息到RocketMQ, 推送消息给该用户, 通知审核通过
            NcMessage message = new NcMessage();
            message.setApplyUserId(sysAllowedJoinCompanyUserDTO.getApplyUserId());
            message.setApplyUsername(companyUser.getUserName());
            message.setMessageType(MessageConstant.COMPANY_APPLY_PASS);
            message.setContent(companyUser.getUserName() + " 加入企业请求,申请通过!");

            message.setApproveUserId(CurrentUserHolder.get().getId());
            message.setApproveUsername(CurrentUserHolder.get().getUsername());
            message.setTargets(Collections.singletonList(companyUser.getMobile()));

            log.info("发送消息到MQ , 推送审核通过的消息给系统管理员 ");
            rocketMQTemplate.convertAndSend("messagePushTopic", message);
        }
    }
}
